import Sprite from './sprite';
import { SCREEN_WIDTH, SCREEN_HEIGHT } from '../render';
import DataBus from '../databus';

const databus = new DataBus();

export default class Character extends Sprite {
  constructor(imgSrc, width, height, frameWidth, canvas = null) {
    super(imgSrc, width, height, frameWidth);
    
    // 保存canvas引用
    this.canvas = canvas;

    // 伤害动画数组
    this.harmAnimations = [];

    // 基础属性
    this.maxHp = 100;        // 默认最大生命值
    this.hp = this.maxHp;    // 当前生命值
    this.attack = 10;        // 默认攻击力
    this.defense = 5;        // 默认防御力
    
    // 移动相关
    this.direction = 'left'; // 朝向：'left' 或 'right'
    this.frameTimer = 0;     // 帧动画计时器
    this.frameInterval = 5;  // 切换帧的间隔
    this.currentFrame = 0;   // 当前动画帧
    
    // 攻击相关
    this.attackTimer = 0;    // 攻击计时器
    this.attackInterval = 60;// 攻击间隔（帧数）
    this.attackRange = 150;  // 默认攻击范围
    this.attackWidth = 100;  // 攻击区域宽度
    this.attackHeight = 80;  // 攻击区域高度
  }

  // 显示伤害数字
  showDamageNumber(damage, isCritical = false) {
    const animation = {
      value: damage,
      x: this.x + this.width / 2,
      y: this.y - 10,
      alpha: 1.0,
      scale: isCritical ? 1.5 : 1.2,
      velocity: -1.5,  // 向上移动的速度
      lifeTime: 30,   // 动画持续时间（帧数）
      isCritical: isCritical
    };
    this.harmAnimations.push(animation);
  }

  // 受到伤害
  takeDamage(damage, attacker = null) {
    // 计算实际伤害（考虑防御力）
    const actualDamage = Math.max(1, damage - this.defense);
    this.hp -= actualDamage;
    
    // 显示伤害数字
    this.showDamageNumber(actualDamage);
    
    // 如果有攻击者，应用击退效果
    if (attacker) {
      this.knockback(attacker);
    }
    
    console.log(`${this.constructor.name} took damage:`, actualDamage, 'HP remaining:', this.hp);
    
    return actualDamage;
  }
  
  // 击退效果
  knockback(attacker, force = 30) {
    // 计算击退方向
    const dx = this.x - attacker.x;
    const dy = this.y - attacker.y;
    
    // 计算距离
    const distance = Math.sqrt(dx * dx + dy * dy);
    
    if (distance === 0) return; // 防止除以零
    
    // 计算单位向量
    const unitX = dx / distance;
    const unitY = dy / distance;
    
    // 应用击退力
    this.x += unitX * force;
    this.y += unitY * force;
    
    // 边界检查
    this.x = Math.max(0, Math.min(SCREEN_WIDTH - this.width, this.x));
    this.y = Math.max(0, Math.min(SCREEN_HEIGHT - this.height, this.y));
    
    // 设置被击退状态
    this.isKnockedBack = true;
    this.knockbackRecoveryTime = 15; // 增加恢复时间到15帧
    
    console.log(`${this.constructor.name} knocked back by ${force} units`);
  }

  // 更新动画帧
  updateAnimation() {
    if (++this.frameTimer >= this.frameInterval) {
      this.frameTimer = 0;
      this.currentFrame = (this.currentFrame + 1) % 4;
    }
  }

  // 移动方法
  move(dx, dy, speed) {
    // 检查输入参数是否有效
    if (isNaN(dx) || isNaN(dy) || isNaN(speed)) {
      console.error('Character.move: 无效的移动参数', { dx, dy, speed });
      return;
    }
    
    // 检查当前位置是否有效
    if (isNaN(this.x) || isNaN(this.y)) {
      console.error('Character.move: 当前位置无效', { x: this.x, y: this.y });
      // 重置到安全位置
      this.x = this.x || 100;
      this.y = this.y || 100;
      return;
    }
    
    // 计算新位置
    const newX = this.x + dx * speed;
    const newY = this.y + dy * speed;
    
    // 检查新位置是否有效
    if (isNaN(newX) || isNaN(newY)) {
      console.error('Character.move: 计算的新位置无效', { oldX: this.x, oldY: this.y, newX, newY });
      return;
    }
    
    // 更新位置
    this.x = newX;
    this.y = newY;
    
    // 边界检查
    this.x = Math.max(0, Math.min(SCREEN_WIDTH - this.width, this.x));
    this.y = Math.max(0, Math.min(SCREEN_HEIGHT - this.height, this.y));
  }

  // 获取攻击区域
  getAttackArea() {
    // 根据朝向计算攻击区域
    const attackX = this.direction === 'left' 
      ? this.x - this.attackRange 
      : this.x + this.width;
    
    const attackY = this.y - (this.attackHeight - this.height) / 2;
    
    return {
      x: attackX,
      y: attackY,
      width: this.attackRange,
      height: this.attackHeight
    };
  }

  // 检查目标是否在攻击范围内
  isTargetInAttackRange(target) {
    // 首先检查是否重叠 - 如果角色重叠，一定在攻击范围内
    if (this.isOverlapping(target)) {
      return true;
    }
    
    // 否则检查是否在攻击区域内
    const attackArea = this.getAttackArea();
    
    // 检查目标的四个角是否有任何一个在攻击区域内
    // 左上角
    if (this.isPointInArea(target.x, target.y, attackArea)) return true;
    // 右上角
    if (this.isPointInArea(target.x + target.width, target.y, attackArea)) return true;
    // 左下角
    if (this.isPointInArea(target.x, target.y + target.height, attackArea)) return true;
    // 右下角
    if (this.isPointInArea(target.x + target.width, target.y + target.height, attackArea)) return true;
    
    // 检查目标中心点是否在攻击区域内
    return this.isPointInArea(
      target.x + target.width / 2,
      target.y + target.height / 2,
      attackArea
    );
  }
  
  // 检查点是否在区域内
  isPointInArea(x, y, area) {
    return x >= area.x && 
           x <= area.x + area.width &&
           y >= area.y && 
           y <= area.y + area.height;
  }
  
  // 检查两个角色是否重叠
  isOverlapping(other) {
    // 检查两个矩形是否重叠
    return !(
      this.x + this.width < other.x ||
      other.x + other.width < this.x ||
      this.y + this.height < other.y ||
      other.y + other.height < this.y
    );
  }

  // 计算与目标的距离
  getDistanceTo(target) {
    const thisCenter = {
      x: this.x + this.width / 2,
      y: this.y + this.height / 2
    };
    
    const targetCenter = {
      x: target.x + target.width / 2,
      y: target.y + target.height / 2
    };
    
    return Math.sqrt(
      Math.pow(thisCenter.x - targetCenter.x, 2) + 
      Math.pow(thisCenter.y - targetCenter.y, 2)
    );
  }

  // 基础渲染方法
  render(ctx) {

    
    if (!this.visible) return;

    ctx.save();
    
    if (this.direction === 'right') {
      // 水平翻转
      ctx.scale(-1, 1);
      ctx.translate(-2 * this.x - this.width, 0);
    }

    // 使用基类的drawToCanvas方法绘制精灵
    this.drawToCanvas(ctx);
    
    ctx.restore();
    
    // 绘制生命条
    this.renderHealthBar(ctx);

    // 调试模式：绘制攻击区域和碰撞箱
    if (databus.debug) {
      // 绘制攻击区域
      const attackArea = this.getAttackArea();
      ctx.save();
      ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
      ctx.fillStyle = 'rgba(255, 0, 0, 0.2)';
      ctx.fillRect(attackArea.x, attackArea.y, attackArea.width, attackArea.height);
      ctx.strokeRect(attackArea.x, attackArea.y, attackArea.width, attackArea.height);
      
      // 绘制角色碰撞箱
      ctx.strokeStyle = 'rgba(0, 255, 0, 0.8)';
      ctx.strokeRect(this.x, this.y, this.width, this.height);
      
      // 绘制中心点
      ctx.fillStyle = 'rgba(255, 255, 0, 1.0)';
      ctx.beginPath();
      ctx.arc(this.x + this.width/2, this.y + this.height/2, 2, 0, Math.PI * 2);
      ctx.fill();
      
      ctx.restore();
    }
  }

  // 绘制生命条
  renderHealthBar(ctx) {
    const hpBarWidth = this.width;
    const hpBarHeight = 4;
    const hpPercentage = Math.max(0, this.hp / this.maxHp);
    
    ctx.save();
    
    ctx.fillStyle = '#333333';
    ctx.fillRect(
      this.x,
      this.y - hpBarHeight - 2,
      hpBarWidth,
      hpBarHeight
    );
    
    ctx.fillStyle = '#00FF00';
    ctx.fillRect(
      this.x,
      this.y - hpBarHeight - 2,
      hpBarWidth * hpPercentage,
      hpBarHeight
    );
    
    ctx.restore();
  }

  // 基础更新方法
  update() {
    this.updateAnimation();
    
    // 处理击退恢复
    if (this.isKnockedBack) {
      if (--this.knockbackRecoveryTime <= 0) {
        this.isKnockedBack = false;
      }
    }
    
    // 更新伤害动画
    for (let i = this.harmAnimations.length - 1; i >= 0; i--) {
      const anim = this.harmAnimations[i];
      anim.y += anim.velocity;  // 向上移动
      anim.alpha -= 0.03;      // 逐渐淡出
      anim.scale -= 0.01;      // 逐渐缩小
      anim.lifeTime--;         // 减少生命时间

      // 如果动画结束，从数组中移除
      if (anim.lifeTime <= 0 || anim.alpha <= 0) {
        this.harmAnimations.splice(i, 1);
      }
    }
  }
  
  // 渲染伤害动画
  renderHarmAnimations(ctx) {
    for (const anim of this.harmAnimations) {
      ctx.save();
      ctx.fillStyle = anim.isCritical ? 
        `rgba(255, 50, 50, ${anim.alpha})` : 
        `rgba(255, 0, 0, ${anim.alpha})`;
      ctx.font = `bold ${Math.floor(16 * anim.scale)}px Arial`;
      ctx.textAlign = 'center';
      ctx.fillText(`-${anim.value}`, anim.x, anim.y);
      ctx.restore();
    }
  }
}